import { Injectable } from '@nestjs/common';
import { SQL, sql } from 'drizzle-orm';
import { DrizzleService } from '../../db/drizzle.service';

export interface PaginationOptions {
  pageNum: number;
  pageSize: number;
}

export interface PaginatedResult<T> {
  data: T[];
  total: number;
  pageNum: number;
  pageSize: number;
  totalPages: number;
}

export interface QueryOptions {
  where?: SQL[];
  orderBy?: SQL;
  select?: any;
}

@Injectable()
export class PaginationService {
  constructor(private readonly drizzle: DrizzleService) {}

  /**
   * 通用分页查询方法
   * @param table 数据库表
   * @param options 分页选项
   * @param queryOptions 查询选项
   * @returns 分页结果
   */
  async paginate<T>(
    table: any,
    options: PaginationOptions,
    queryOptions: QueryOptions = {}
  ): Promise<PaginatedResult<T>> {
    const { pageNum = 1, pageSize = 10 } = options;
    const offset = (pageNum - 1) * pageSize;

    // 构建查询条件
    const conditions = queryOptions.where || [];

    // 查询总数
    const [countResult] = await this.drizzle.db
      .select({ count: sql<number>`count(*)` })
      .from(table)
      .where(conditions.length > 0 ? sql.join(conditions, sql` and `) : undefined);

    const total = countResult.count;

    // 查询分页数据
    let query = this.drizzle.db
      .select(queryOptions.select)
      .from(table)
      .where(conditions.length > 0 ? sql.join(conditions, sql` and `) : undefined)
      .limit(pageSize)
      .offset(offset);

    // 添加排序
    if (queryOptions.orderBy) {
      query = query.orderBy(queryOptions.orderBy);
    }

    const data = await query;

    return {
      data: data as T[],
      total,
      pageNum,
      pageSize,
      totalPages: Math.ceil(total / pageSize)
    };
  }

  /**
   * 构建模糊查询条件
   * @param field 字段
   * @param value 查询值
   * @returns SQL条件
   */
  buildLikeCondition(field: any, value: string): SQL {
    return sql`${field} like ${`%${value}%`}`;
  }

  /**
   * 构建等于查询条件
   * @param field 字段
   * @param value 查询值
   * @returns SQL条件
   */
  buildEqualCondition(field: any, value: any): SQL {
    return sql`${field} = ${value}`;
  }

  /**
   * 计算偏移量
   * @param pageNum 页码
   * @param pageSize 每页条数
   * @returns 偏移量
   */
  calculateOffset(pageNum: number, pageSize: number): number {
    return (pageNum - 1) * pageSize;
  }

  /**
   * 计算总页数
   * @param total 总记录数
   * @param pageSize 每页条数
   * @returns 总页数
   */
  calculateTotalPages(total: number, pageSize: number): number {
    return Math.ceil(total / pageSize);
  }
}